// Fill out your copyright notice in the Description page of Project Settings.

#include "requestHttpInfo.h"
#include "HttpModule.h"
#include "IHttpResponse.h"


const FString FMKSimpleHttpRequestData::Conten_Type = "Content-Type";
const FString FMKSimpleHttpRequestData::User_Agent = "User-Agent";
const FString FMKSimpleHttpRequestData::KeyValueContent = "application/x-www-form-urlencoded;charset=utf-8";
const FString FMKSimpleHttpRequestData::UTF8JsonContent = "application/json;charset=utf-8";
const FString FMKSimpleHttpRequestData::MultipartOrformDataContent = "multipart/form-data";
const FString FMKSimpleHttpRequestData::OctetStreamContent = "application/octet-stream";



FMKSimpleHttpRequestData::FMKSimpleHttpRequestData():
	typ(EMK_SimpleHttpPostTyp::POST), url(""), data("")
{

}

FMKSimpleHttpRequestData::FMKSimpleHttpRequestData(EMK_SimpleHttpPostTyp typ_, FString url_, FString ContentType_, FString data_) :
	typ(typ_), url(url_),data(data_)
{

}


void FMKSimpleHttpRequestData::TryFinishUpHard() 
{
	if (!hardMap.Contains(Conten_Type))
	{
		hardMap.Add(Conten_Type, KeyValueContent);
	}
	if (!hardMap.Contains(User_Agent))
	{
		hardMap.Add(User_Agent,"X-UnrealEngine-Agent");
	}
}


FString FMKSimpleHttpRequestData::GetHttpVerb(EMK_SimpleHttpPostTyp typ)
{
	switch (typ)
	{
	case EMK_SimpleHttpPostTyp::GET:
		return TEXT("GET");
		break;
	case EMK_SimpleHttpPostTyp::POST:
		return TEXT("POST");
		break;
	case EMK_SimpleHttpPostTyp::PUT:
		return TEXT("PUT");
		break;
	case EMK_SimpleHttpPostTyp::Delete:
		return TEXT("delete");
		break;
	default:
		return TEXT("POST");
		break;
	}
	return TEXT("POST");
}


bool FManKuPostEvent::SetNewData(FMKSimpleHttpRequestData data_)
{
	if (typ != EMK_SimpleHttpLifeTyp::WaitBack)
	{
		typ = EMK_SimpleHttpLifeTyp::WaitStart;
		data = data_;
		return true;
	}
	return false;
}
bool FManKuPostEvent::SetCallBackEvent(F_SimpleHttpServerReturn e)
{
	backEvent.Clear();
	backEvent = e;
	return backEvent.IsBound();
}

bool FManKuPostEvent::StartPost()
{
	dataBuffer.Empty();
	backData.Empty();
	if (typ == EMK_SimpleHttpLifeTyp::WaitStart)
	{
		data.TryFinishUpHard();
		TSharedRef<IHttpRequest> FileUploadRequest = FHttpModule::Get().CreateRequest();
		FileUploadRequest->SetVerb(FMKSimpleHttpRequestData::GetHttpVerb(data.typ));
		for (auto& hards : data.hardMap)
		{

			FileUploadRequest->SetHeader(hards.Key, hards.Value);
			
		}

		FileUploadRequest->SetURL(data.url);
		if (data.data.Len() > 8)
		{
			FileUploadRequest->SetContentAsString(data.data);
		}

		FileUploadRequest->OnProcessRequestComplete().BindRaw(this, &FManKuPostEvent::HttpCallBack);
		if (FileUploadRequest->ProcessRequest())
		{
			typ = EMK_SimpleHttpLifeTyp::WaitBack;

		}
		else
		{
			backData = "FManKuPostEvent::StartPost() false!!";
			OnSaverBack();
		}
		return true;
	}
	return false;
}

void FManKuPostEvent::HttpCallBack(FHttpRequestPtr Request, FHttpResponsePtr Response, bool bWasSuccessful)
{
	// If HTTP fails client-side, this will still be called but with a NULL shared pointer!
	if (!Response.IsValid())
	{
		backData = "{\"success\":\"Error: Unable to process HTTP Request!\"}";
	}
	else
	{
		if (EHttpResponseCodes::IsOk(Response->GetResponseCode()))
		{
			dataBuffer = TArray<uint8>(Response->GetContent());
			backData = Response->GetContentAsString();
		}
		else
		{
			backData = FString::Printf(TEXT("{\"success\":\"HTTP Error: %d\"}"), Response->GetResponseCode());
		}
	}
	GLog->Log(FString::Printf(TEXT("server back:\n %s \n leng = %i \n\n\n .............................."), *backData, backData.Len()));
	OnSaverBack();
}

void FManKuPostEvent::OnSaverBack()
{

	if (backEvent.IsBound())
	{
		backEvent.Execute(backData);
	}
	typ = EMK_SimpleHttpLifeTyp::BackOker;
}

void FManKuPostEvent::ReadBackData(FString* str, TArray<uint8>* buff)
{
	if (str)
	{
		*str = backData;
	}

	if (buff)
	{
		*buff = dataBuffer;
	}
}